package com.kzw.oa.system.model;

import com.kzw.misc.utils.AppUtil;
import com.kzw.oa.system.bean.TopModule;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import java.io.Serializable;
import java.util.*;

@Entity
@Table(name = "app_user")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class AppUser implements UserDetails, Serializable {
	
	private static final long serialVersionUID = 8672045713593419630L;
	/**
	 * 超级管理员ID,由初始化数据加入
	 */
	public static final Long SUPER_USER = new Long(1);

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long userId;

	// 账号
	@Column(unique = true, length = 50)
	private String username;

	// 密码
	@Column(length = 50)
	private String password;

	// 邮件
	@Column(length = 100)
	private String email;

	// 所属部门
	@ManyToOne
	@JoinColumn(name = "dept_id")
	private Department dept;

	// 电话
	@Column(length = 50)
	private String phone;

	// 手机
	@Column(length = 50)
	private String mobile;

	// 传真
	@Column(length = 50)
	private String fax;

	// 地址
	private String address;

	// 邮编
	@Column(length = 50)
	private String zip;

	// 头像
	private String photo;
	// 访问时间
	private Date accessionTime = new Date();
	// 状态
	private Integer status;
	// 性别
	private Integer gender;

	// 真实姓名
	@Column(length = 50)
	private String fullname;

	// 是否删除
	private Integer delFlag;

	// 角色名称
	@Transient
	private String roleNames;

	// 用户所属部门的优先级 
	private Integer orgSn;

	// 用户在此部门中的优先级
	private Integer userSn;

	// 角色
	@ManyToMany
	@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
	private Set<AppRole> roles = new HashSet<AppRole>();

	/**
	 * 用户与部门可能是多对多关系（如一个用户可能是多个部门的领导）
	 */
	@OneToMany(mappedBy = "appUser")
	private Set<UserOrg> orgs = new HashSet<UserOrg>();

	/**
	 * 用户头部的模块菜单，由用户登录后设置
	 */
	@Transient
	private Map<String, TopModule> topModules = new LinkedHashMap<String, TopModule>();

	/**
	 * 用于存储该用户的权限,需要合并公共的
	 */
	@Transient
	private Set<String> rights = new HashSet<String>();

	public Set<String> getRights() {
		return rights;
	}

	public Map<String, TopModule> getTopModules() {
		return topModules;
	}

	public void setTopModules(Map<String, TopModule> topModules) {
		this.topModules = topModules;
	}

	/**
	 * 取得所有的Function的权限，则以_为开头的权限
	 */
	public String getFunctionRights() {
		StringBuffer sb = new StringBuffer();

		Iterator<String> it = rights.iterator();

		while (it.hasNext()) {
			sb.append(it.next()).append(",");
		}

		if (rights.size() > 0) {
			sb.deleteCharAt(sb.length() - 1);
		}

		return sb.toString();
	}

	/**
	 * 取得用户所在部门
	 */
	public String getDepNames() {
		String depNames = "";
//		Iterator<UserOrg> it = getOrgs().iterator();
//		while (it.hasNext()) {
//			UserOrg userOrg = it.next();
//			depNames += userOrg.getDept().getDepName() + ",";
//		}
//		if (depNames.length() > 0) {
//			depNames = depNames.substring(0, depNames.length() - 1);
//		}
		if(dept != null) return dept.getDepName();
		return depNames;
	}

	public void setRights(Set<String> rights) {
		this.rights = rights;
	}

	public AppUser() {
	}

	public AppUser(Long in_userId) {
		this.setUserId(in_userId);
	}

	public Long getUserId() {
		return this.userId;
	}

	public void setUserId(Long aValue) {
		this.userId = aValue;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(String aValue) {
		this.username = aValue;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String aValue) {
		this.password = aValue;
	}

	public String getEmail() {
		return this.email;
	}

	public void setEmail(String aValue) {
		this.email = aValue;
	}

	public String getPhone() {
		return this.phone;
	}

	public void setPhone(String aValue) {
		this.phone = aValue;
	}

	public String getMobile() {
		return this.mobile;
	}

	public void setMobile(String aValue) {
		this.mobile = aValue;
	}

	public String getFax() {
		return this.fax;
	}

	public void setFax(String aValue) {
		this.fax = aValue;
	}

	public String getAddress() {
		return this.address;
	}

	public void setAddress(String aValue) {
		this.address = aValue;
	}

	public String getZip() {
		return this.zip;
	}

	public void setZip(String aValue) {
		this.zip = aValue;
	}

	public String getPhoto() {
		return this.photo;
	}

	public void setPhoto(String aValue) {
		this.photo = aValue;
	}

	public java.util.Date getAccessionTime() {
		return this.accessionTime;
	}

	public void setAccessionTime(java.util.Date aValue) {
		this.accessionTime = aValue;
	}

	public Integer getStatus() {
		return this.status;
	}

	public void setStatus(Integer aValue) {
		this.status = aValue;
	}

	public String getFullname() {
		return this.fullname;
	}

	public void setFullname(String aValue) {
		this.fullname = aValue;
	}

	public Integer getDelFlag() {
		return delFlag;
	}

	public void setDelFlag(Integer delFlag) {
		this.delFlag = delFlag;
	}

	/**
	 * Return the name of the first key column
	 */
	public String getFirstKeyColumnName() {
		return "userId";
	}

	public Set<AppRole> getRoles() {
		return roles;
	}

	public void setRoles(Set<AppRole> roles) {
		this.roles = roles;
	}

	// public GrantedAuthority[] getAuthorities() {
	// GrantedAuthority[] rights = roles.toArray(new
	// GrantedAuthority[roles.size() + 1]);
	// rights[rights.length - 1] = new GrantedAuthorityImpl("ROLE_PUBLIC");
	// return rights;
	// }

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		List<GrantedAuthority> rights = new ArrayList<GrantedAuthority>();
		for (AppRole role : roles) {
			rights.add(role);
		}
		return rights;
	}

	public boolean isAccountNonExpired() {
		return true;
	}

	public boolean isAccountNonLocked() {
		return true;
	}

	public boolean isCredentialsNonExpired() {
		return true;
	}

	public boolean isEnabled() {
		if (status == 1) {
			return true;
		}
		return false;
	}

	// overwrite for

	/**
	 * Return the Id (pk) of the entity
	 */
	public String getId() {
		return userId.toString();
	}
	
	public String getBusinessEmail() {
		return email;
	}

	public String getFamilyName() {
		return fullname;
	}

	public String getGivenName() {
		return fullname;
	}

	/**
	 * 是否超级管理员角色
	 * */
	public boolean isSupperManage() {
		Set<AppRole> roles = getRoles();
		boolean flag = false;
		for (Iterator<AppRole> it = roles.iterator(); it.hasNext();) {
			AppRole role = it.next();
			if (role.getRoleId().equals(AppRole.SUPER_ROLEID)) {
				flag = true;
			}
		}
		return flag;
	}

	public Set<UserOrg> getOrgs() {
		return orgs;
	}

	public void setOrgs(Set<UserOrg> orgs) {
		this.orgs = orgs;
	}

	/**
	 * 取得用户所拥有的角色
	 */
	public String getRoleNames() {
		roleNames = "";
		Iterator<AppRole> it = getRoles().iterator();
		while (it.hasNext()) {
			AppRole ar = it.next();
			roleNames += ar.getRoleName() + ",";
		}
		if (roleNames.length() > 0) {
			roleNames = roleNames.substring(0, roleNames.length() - 1);
		}
		return roleNames;
	}

	/**
	 * 是否为超级管理员
	 */
	public boolean isSuperAdmin() {
		Iterator<AppRole> it = getRoles().iterator();
		while (it.hasNext()) {
			AppRole ar = it.next();
			if ("超级管理员".equals(ar.getRoleName())) {
				return true;
			}
		}
		return false;
	}

	public void setRoleNames(String roleNames) {
		this.roleNames = roleNames;
	}

	/**
	 * 初始化
	 * */
	public void init() {
		// 进行合并权限的处理
		Set<AppRole> roleSet = getRoles();
		Iterator<AppRole> it = roleSet.iterator();

		while (it.hasNext()) {
			AppRole role = it.next();
			if (role.getRoleId().equals(AppRole.SUPER_ROLEID)) {// 具有超级权限
				getRights().clear();
				getTopModules().clear();
				getRights().add(AppRole.SUPER_RIGHTS);
				getTopModules().putAll(AppUtil.getAllTopModels());
				break;
			} else {
				if (StringUtils.isNotEmpty(role.getRights())) {
					String[] items = role.getRights().split("[,]");
					for (int i = 0; i < items.length; i++) {
						String item = items[i];
						// 代表模板菜单,即上面的菜单
						if (item.startsWith("Mod_")) {
							if (!getTopModules().containsKey(item)) {
								getTopModules().put(items[i], AppUtil.getAllTopModels().get(item));
							}
							continue;
						}
						if (!getRights().contains(item)) {
							getRights().add(item);
						}
					}
				}
			}
		}

	}

	/**
	 * 初始化菜单权限信息
	 */
	public void initMenuRights() {
		// 取得公共TopMenuId
		getTopModules().putAll(AppUtil.getPublicTopModules());

		// 进行合并权限的处理
		Set<AppRole> roleSet = getRoles();
		Iterator<AppRole> it = roleSet.iterator();

		while (it.hasNext()) {
			AppRole role = it.next();
			if (role.getRoleId().equals(AppRole.SUPER_ROLEID)) {// 具有超级权限
				getRights().clear();
				getTopModules().clear();
				getRights().add(AppRole.SUPER_RIGHTS);
				getTopModules().putAll(AppUtil.getAllTopModels());
				break;
			} else {
				if (StringUtils.isNotEmpty(role.getRights())) {
					String[] items = role.getRights().split("[,]");
					for (int i = 0; i < items.length; i++) {
						String item = items[i];
						// 代表模板菜单,即上面的菜单
						if (item.startsWith("Mod_")) {
							if (!getTopModules().containsKey(item)) {
								getTopModules().put(items[i], AppUtil.getAllTopModels().get(item));
							}
							continue;
						}
						if (!getRights().contains(item)) {
							getRights().add(item);
						}
					}
				}
			}
		}

		// 排序用户的topModules;
		List<TopModule> list = new ArrayList<TopModule>();
		list.addAll(getTopModules().values());
		Collections.sort(list, new Comparator<TopModule>() {
			public int compare(TopModule o1, TopModule o2) {
				if (o1.getSn() > o2.getSn()) {
					return 1;
				}
				return 0;
			}
		});
		getTopModules().clear();
		for (TopModule topMod : list) {
			getTopModules().put(topMod.getId(), topMod);
		}
	}

	public Integer getOrgSn() {
		return orgSn;
	}

	public void setOrgSn(Integer orgSn) {
		this.orgSn = orgSn;
	}

	public Integer getUserSn() {
		return userSn;
	}

	public void setUserSn(Integer userSn) {
		this.userSn = userSn;
	}

	public Department getDept() {
		return dept;
	}

	public void setDept(Department dept) {
		this.dept = dept;
	}

	public Integer getGender() {
		return gender;
	}

	public void setGender(Integer gender) {
		this.gender = gender;
	}

}
